/**
 *  Copyright Matt Silbernagel 2010
 *  
 *	This file is part of MobilePrinting.
 *
 *	MobilePrinting is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  MobilePrinting is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with MobilePrinting.  If not, see <http://www.gnu.org/licenses/>.
 */

package edu.uc.labs.MobilePrinting.OSUtils;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ConnectException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import edu.uc.labs.MobilePrinting.Fetch.XSDFetcher;
import edu.uc.labs.MobilePrinting.GUI.*;
import static edu.uc.labs.MobilePrinting.Configurator.*;

/**
 * A class that checks for and installs needed files for the MobilePrint Project
 * 
 * @author Matt Silbernagel
 */
public class Installer {

	public boolean installed = false;

	/*
	 * The directory structure should look like this: installDir/ cache/ icons/
	 * tray.png tray_mac.png logs/ ppd/ drivers/
	 */
	
	private HashMap<String, String> dirMap;
	

	public String trayIcon = null;
	public String startup_script = null;
	/**
	 * Set up the directory structure
	 */
	public Installer() {
		
		// Get a HashMap of all the needed directories
		dirMap = getDirectoryMap();
		
		if (OS.equalsIgnoreCase("windows 7")){
			startup_script = "win_startup7.bat";
		}
		if (OS.equalsIgnoreCase("windows xp")){
			startup_script = "win_startupxp.bat";
		}
		if (OS.startsWith("Mac")){
			startup_script = "mac_startup.sh";
		}
	}

	public boolean install() {

		
		Collection<String> c = dirMap.values();
		Iterator<String> itr = c.iterator();
		
		while(itr.hasNext()) {
		    File f = new File((String) itr.next());
		    if(!f.exists()){
		    	LOGGER.debug(f.getPath() + " does not exist, attempting to create...");
		    	if(f.mkdirs()){
		    			LOGGER.debug("Successfully create the directory " + f.getPath());
		    	}  else {
		    		LOGGER.error("Unable to create the directory " + f.getPath());
		    	}
		    }
		}
		
		//Files...
		File f4a = new File(getDirectoryMap().get("prefs") +  DELIM +  DEFAULT_CONF);
		File f4b = new File( getDirectoryMap().get("prefs") + DELIM + USER_CONF);
		File f5 = new File(getDirectoryMap().get("userspace") +  XMLVALIDATE );
		File f6 = new File(getDirectoryMap().get("scripts") +  DELIM +  startup_script);
		File f8 = new File( getDirectoryMap().get("icons") + DELIM + MAINIMAGE);
		
		for(int i = 0; i < trayicon.length; i++){
			File f = new File(getDirectoryMap().get("icons") + DELIM + IconArray.get(trayicon[i]));
			if (!f.exists()) {
				LOGGER.debug("I need to put the image in the correct directory...");		
				installFile("/edu/uc/labs/MobilePrinting/images" +  DELIM +  IconArray.get(trayicon[i]), getDirectoryMap().get("icons")
							+  DELIM + IconArray.get(trayicon[i]));
			}
		}
		
		if (!f5.exists()) {
			LOGGER.debug("I need to get the xsd...");
			XSDFetcher xsd;
			//Download and create the file
			try {
				xsd = new XSDFetcher();
				FileWriter fstream = new FileWriter(f5.getAbsolutePath());
				BufferedWriter out = new BufferedWriter(fstream);
				out.write(xsd.getResponse());
				out.close();
			} catch (ConnectException e) {
				LOGGER.error("Cannot connect to the server to get the XML Validation");
				System.exit(1);
			} catch (IOException e) {
				LOGGER.error("IOException trying to get the XSD from " + HTTP_SERVER);
				LOGGER.error("Could not write the file " + XMLVALIDATE);
				e.printStackTrace();
			}
			
			
			
		}
	
		if(!f6.exists()) {
			LOGGER.debug("I need to put the startup script in the correct directory... ");
			installFile("../scripts" +  DELIM + STARTUP_SCRIPT, getDirectoryMap().get("scripts"));
		}
		
		
		if(!f8.exists()){
			LOGGER.debug("Need to put the mainimage in the icons directory ");
			installFile("../images" + DELIM + MAINIMAGE, getDirectoryMap().get("icons") + DELIM + MAINIMAGE);
		}

		/*
		 * Check for the defaults.xml file. If its not there then copy it
		 * from the .jar 
		 */

		if (!f4a.exists()) {
			// defaults.xml is not in the directory, check for user.xml
			if(!f4b.exists()){
				LOGGER.debug("Looks like this is the first time MobilePrinting has run, lets set it up...");
				SetupPanel sa = new SetupPanel("Setup");
				while(sa.mainFrame.isVisible()){
					//LOGGER.debug("mainFrame is visable...");
				}
				LOGGER.debug("mainFrame is done...");
				if (sa.isDone()){
					installed = true;
				} else {
					LOGGER.debug("The value of installed is " + SanityCheck.boolToString(sa.done));
				}
			}
		} else {
			installed = true;
		}
		return installed;
	
	}

	/**
	 * 
	 * @return true if all files are installed, false otherwise
	 */
	public boolean isInstalled() {
		return installed;
	}
	
	public void installFile(String jarFile, String fileSystem){
		try {
			LOGGER.debug(this.getClass().getCanonicalName());
			InputStream is = this.getClass().getResourceAsStream( jarFile );
			LOGGER.debug(is.toString());
			
			OutputStream os = new FileOutputStream(fileSystem);
			byte[] buffer = new byte[10000];
			int length;
			while ((length = is.read(buffer)) > 0) {
				os.write(buffer, 0, length);
			}
			os.close();
			is.close();
		} catch (Exception e) {
			LOGGER.debug(e.toString());
		}
	}

}
